package wei.qiang.ye.dynamicdatasourcemybatis.service;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import wei.qiang.ye.dynamicdatasourcemybatis.constant.DBConstants;
import wei.qiang.ye.dynamicdatasourcemybatis.domain.OrderDO;
import wei.qiang.ye.dynamicdatasourcemybatis.domain.UserDO;
import wei.qiang.ye.dynamicdatasourcemybatis.mapper.order.OrderMapper;
import wei.qiang.ye.dynamicdatasourcemybatis.mapper.user.UserMapper;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;

    private OrderService self() {
        return (OrderService) AopContext.currentProxy();
    }

    public void method01() {
        // 查询订单
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
        // 查询用户
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }

    /**
     * 在 @Transactional 注解上，如果未设置使用的事务管理器，它会去选择一个事务管理器。
     * 我们这里创建了 ordersTransactionManager 和 usersTransactionManager 两个事务管理器，它就不知道怎么选了。
     * 它只好抛出 NoUniqueBeanDefinitionException 异常。
     */
    @Transactional // 报错，找不到事务管理器
    public void method02() {
        // 查询订单
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
        // 查询用户
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }

    public void method03() {
        // 查询订单
        self().method03_1();
        // 查询用户
        self().method03_2();
    }

    @Transactional(transactionManager = DBConstants.TX_MANAGER_ORDERS)
    public void method03_1() {
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
    }

    @Transactional(transactionManager = DBConstants.TX_MANAGER_USERS)
    public void method03_2() {
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }

    @Transactional(transactionManager = DBConstants.TX_MANAGER_ORDERS)
    public void method05() {
        // 查询订单
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
        // 查询用户
        self().method05_2();
    }

    /**
     * 这里使用的事务传播级别是 Propagation.REQUIRES_NEW 。此时，在执行 #method05_2() 方法之前，
     * TransactionInterceptor 会将原事务挂起，暂时性的将原事务信息和当前线程解绑。
     * 在执行 #method05_2() 方法前，又可以执行一轮事务的逻辑。
     * 在执行 #method05_2() 方法完成后，会将原事务恢复，重新将原事务信息和当前线程绑定。
     */
    @Transactional(transactionManager = DBConstants.TX_MANAGER_USERS,
            propagation = Propagation.REQUIRES_NEW)
    public void method05_2() {
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }

}
